#include "model/DHT11.h"
#include "model/OneWire.hpp"
#include <catch2/catch_test_macros.hpp>

TEST_CASE("16 bits 1-wire", "[one_wire]") {
  using Model = model::OneWire<2>;
  auto model = Model();
  model.toggle(5);
  model.toggle(22);

  model.toggle(40);
  model.toggle(70);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(70);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(70);
  CHECK(model.data[1] == 0b10010001);

  model.toggle(40);
  model.toggle(70);

  model.toggle(40);
  model.toggle(70);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(10);

  model.toggle(40);
  model.toggle(10);

  CHECK(!model.toggle(40));
  CHECK(model.toggle(10));
  CHECK(model.data[0] == 0b11000000);
}

TEST_CASE("40 bits 1-wire", "[one_wire]") {
  using Model = model::OneWire<5>;
  auto model = Model();

  model.toggle(65);
  model.toggle(86);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(70);
  model.toggle(53);
  model.toggle(70);
  model.toggle(53);
  model.toggle(70);
  model.toggle(54);
  model.toggle(70);
  model.toggle(53);
  model.toggle(25);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(25);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(23);
  model.toggle(53);
  model.toggle(70);
  model.toggle(54);
  model.toggle(70);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(70);
  model.toggle(53);
  model.toggle(71);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(23);
  model.toggle(53);
  model.toggle(69);
  model.toggle(54);
  model.toggle(70);
  model.toggle(53);
  model.toggle(25);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(24);
  model.toggle(53);
  model.toggle(70);
  model.toggle(53);
  model.toggle(70);
  model.toggle(53);
  model.toggle(70);
  model.toggle(54);
  model.toggle(70);
  model.toggle(53);
  model.toggle(72);
  model.toggle(51);
  auto done = model.toggle(69);
  CHECK(done);
  CHECK(model.data[4] == 0b00011110);
  CHECK(model.data[3] == 0);
  CHECK(model.data[2] == 0b00011011);
  CHECK(model.data[1] == 0b00000110);
  CHECK(model.data[0] == 0b00111111);
}

TEST_CASE("dht11", "[dht11]") {
  using Wire = model::OneWire<5>;
  auto wire = Wire();

  SECTION("valid") {
    wire.data[4] = 0b00011110;
    wire.data[3] = 0;
    wire.data[2] = 0b00011011;
    wire.data[1] = 0b00000110;
    wire.data[0] = 0b00111111;

    auto opt = model::DHT11::construct(wire);
    REQUIRE(opt);
    auto &model = opt.value();
    CHECK(model.humidity().integral == 30);
    CHECK(model.humidity().decimal == 0);
    CHECK(model.temperature().integral == 27);
    CHECK(model.temperature().decimal == 6);
  }

  SECTION("invalid") {
    wire.data[0] = 1;
    REQUIRE(!model::DHT11::construct(wire));
  }
}
